package server;

import java.util.Random;

public class ScheduleIndividual implements GenericIndividual {

	private int [] gene;
	private double fitness;
	
	private int tSlots;
	private int nClasses;
	
	private ScheduleConflicts sCons;
	
	public ScheduleIndividual(int nClass, int tSlot, ScheduleConflicts sCon) {
		
		tSlots = tSlot;
		gene = new int [nClass];
		sCons = sCon;
	}

	/**
	 * This creates an array of length equal to the number of classes
	 * available, and puts them each at a random time slot- determined randomly
	 * to be anything from 0 to the number of potential time slots minus 1. The
	 * individual then calculates its own fitness, and sets that equal to the
	 * ScheduleIndividual's fitness parameter. 
	 */
	public void populateRandomly() {
		
		Random rand = new Random();
		
		for (int i = 0; i < gene.length; i++){
			
			//For class number i, places it at a random time slot numbering
			//from 0 to tSlots-1 (still covers the correct number of time
			//slots, just begin counting at 0, instead of 1 to tSlots)
			gene[i] = rand.nextInt(tSlots);
		}
		fitness = calculateFitness();
	}

	@Override
	public void populateFromCS() {
		// TODO Auto-generated method stub

	}
/*	public int[][] getGene(){
		return gene;
	}*/
	public double getFitness(){
		return fitness;
	}

	//Instead of using this an an external thing, let's have it be a 
	//private method that can be used by populateRandomly and populateFromCS.
	/**
	 * This loops through all potential pairs of elements in the ScheduleIndividual's
	 * gene, and determines what percentage of all potential conflicts within the
	 * {@link ScheduleConflicts} actually exist in the gene. This does not compare an
	 * element to itself as a potential conflict.
	 * <p>
	 * @return This returns the fitness of the gene in this ScheduleIndividual.
	 */
	private double calculateFitness() {
		
		int conflicts = 0;
		//Make a double so that integer division doesn't get screwed up
		double possibleConflicts = 0;
		
		//Iterrate through our and compare each of the two elements.
		//Start at 1 less than the length, since that will be the actual
		//index of the last element.
		for (int i = gene.length -1; i > 0; i--){
			for (int j = 0; j < i; j++){
				
				//If these classes are scheduled in the same time slot, and
				//there is a student who has a conflict
				if (gene[i] == gene[j] && sCons.conflicts[i][j] == 1){
					conflicts++;
				}
				//TODO
				//Is this an accurate representation of all potential conflicts
				//within the system? Should a class and itself count as a
				//potential conflict?
				possibleConflicts++;
			}
		}
		double fit = 1 - (conflicts/possibleConflicts);
		return fit;
	}
}
